Option Strict Off
Option Explicit On

Imports System.IO
Public Module mod_BikiUSB
    Public Declare Function FT_GetNumberOfDevices Lib "BIKIUSB.DLL" Alias "FT_ListDevices" (ByRef lngNumberOfDevices As Integer, ByVal pvArg2 As String, ByVal lngFlags As Integer) As FT_return
    Public Declare Function FT_GetDeviceString Lib "BIKIUSB.DLL" Alias "FT_ListDevices" (ByVal lngDeviceIndex As Integer, ByVal lpszDeviceString As String, ByVal lngFlags As Integer) As FT_return
    Public Declare Function FT_GetDeviceInfo Lib "BIKIUSB.DLL" (ByVal lngHandle As Integer, ByRef lngFT_Type As Integer, ByRef lngID As Integer, ByVal pucSerialNumber As String, ByVal pucDescription As String, ByRef pvDummy As Byte) As FT_return

    '===========================================================================================================================
    ' Declarations for functions in FTD2XX.dll:
    '===========================================================================================================================
    Public Declare Function FT_OpenByIndex Lib "BIKIUSB.DLL" Alias "FT_Open" (ByVal intDeviceNumber As Integer, ByRef lngHandle As Integer) As FT_return
    Public Declare Function FT_OpenBySerialNumber Lib "BIKIUSB.DLL" Alias "FT_OpenEx" (ByVal SerialNumber As String, ByVal lngFlags As Integer, ByRef lngHandle As Integer) As FT_return
    Public Declare Function FT_OpenByDescription Lib "BIKIUSB.DLL" Alias "FT_OpenEx" (ByVal Description As String, ByVal lngFlags As Integer, ByRef lngHandle As Integer) As FT_return
    Public Declare Function FT_Close Lib "BIKIUSB.DLL" (ByVal lngHandle As Integer) As FT_return
    Public Declare Function FT_Read_String Lib "BIKIUSB.DLL" Alias "FT_Read" (ByVal lngHandle As Integer, ByVal lpvBuffer As String, ByVal lngBufferSize As Integer, ByRef lngBytesReturned As Integer) As FT_return
    Public Declare Function FT_Write_String Lib "BIKIUSB.DLL" Alias "FT_Write" (ByVal lngHandle As Integer, ByVal lpvBuffer As String, ByVal lngBufferSize As Integer, ByRef lngBytesWritten As Integer) As FT_return
    Public Declare Function FT_Read_Bytes Lib "BIKIUSB.DLL" Alias "FT_Read" (ByVal lngHandle As Integer, ByRef lpvBuffer As Byte, ByVal lngBufferSize As Integer, ByRef lngBytesReturned As Integer) As FT_return
    Public Declare Function FT_Write_Bytes Lib "BIKIUSB.DLL" Alias "FT_Write" (ByVal lngHandle As Integer, ByRef lpvBuffer As Byte, ByVal lngBufferSize As Integer, ByRef lngBytesWritten As Integer) As FT_return
    Public Declare Function FT_SetBaudRate Lib "BIKIUSB.DLL" (ByVal lngHandle As Integer, ByVal lngBaudRate As Integer) As FT_return
    Public Declare Function FT_SetDivisor Lib "BIKIUSB.DLL" (ByVal lngHandle As Integer, ByVal intDivisor As Integer) As FT_return
    Public Declare Function FT_SetDataCharacteristics Lib "BIKIUSB.DLL" (ByVal lngHandle As Integer, ByVal byWordLength As FT_Bits, ByVal byStopBits As FT_Stop_Bits, ByVal byParity As FT_Parity) As FT_return
    Public Declare Function FT_SetFlowControl Lib "BIKIUSB.DLL" (ByVal lngHandle As Integer, ByVal intFlowControl As FT_Flow, ByVal byXonChar As Byte, ByVal byXoffChar As Byte) As FT_return
    Public Declare Function FT_ResetDevice Lib "BIKIUSB.DLL" (ByVal lngHandle As Integer) As FT_return
    Public Declare Function FT_SetDtr Lib "BIKIUSB.DLL" (ByVal lngHandle As Integer) As FT_return
    Public Declare Function FT_ClrDtr Lib "BIKIUSB.DLL" (ByVal lngHandle As Integer) As FT_return
    Public Declare Function FT_SetRts Lib "BIKIUSB.DLL" (ByVal lngHandle As Integer) As FT_return
    Public Declare Function FT_ClrRts Lib "BIKIUSB.DLL" (ByVal lngHandle As Integer) As FT_return
    Public Declare Function FT_GetModemStatus Lib "BIKIUSB.DLL" (ByVal lngHandle As Integer, ByRef lngModemStatus As Integer) As FT_return
    Public Declare Function FT_SetChars Lib "BIKIUSB.DLL" (ByVal lngHandle As Integer, ByVal byEventChar As Byte, ByVal byEventCharEnabled As Byte, ByVal byErrorChar As Byte, ByVal byErrorCharEnabled As Byte) As FT_return
    Public Declare Function FT_Purge Lib "BIKIUSB.DLL" (ByVal lngHandle As Integer, ByVal lngMask As FT_Purg) As FT_return
    Public Declare Function FT_SetTimeouts Lib "BIKIUSB.DLL" (ByVal lngHandle As Integer, ByVal lngReadTimeout As Integer, ByVal lngWriteTimeout As Integer) As FT_return
    Public Declare Function FT_GetQueueStatus Lib "BIKIUSB.DLL" (ByVal lngHandle As Integer, ByRef lngRxBytes As Integer) As FT_return
    Public Declare Function FT_GetLatencyTimer Lib "BIKIUSB.DLL" (ByVal lngHandle As Integer, ByRef ucTimer As Byte) As FT_return
    Public Declare Function FT_SetLatencyTimer Lib "BIKIUSB.DLL" (ByVal lngHandle As Integer, ByVal ucTimer As Byte) As FT_return
    Public Declare Function FT_GetBitMode Lib "BIKIUSB.DLL" (ByVal lngHandle As Integer, ByRef ucMode As Byte) As FT_return
    Public Declare Function FT_SetBitMode Lib "BIKIUSB.DLL" (ByVal lngHandle As Integer, ByVal ucMask As Byte, ByVal ucEnable As Byte) As FT_return
    Public Declare Function FT_SetUSBParameters Lib "BIKIUSB.DLL" (ByVal lngHandle As Integer, ByVal lngInTransferSize As Integer, ByVal lngOutTransferSize As Integer) As FT_return
    Public Declare Function FT_SetBreakOn Lib "BIKIUSB.DLL" (ByVal lngHandle As Integer) As FT_return
    Public Declare Function FT_SetBreakOff Lib "BIKIUSB.DLL" (ByVal lngHandle As Integer) As FT_return
    Public Declare Function FT_GetStatus Lib "BIKIUSB.DLL" (ByVal lngHandle As Integer, ByRef lngamountInRxQueue As Integer, ByRef lngAmountInTxQueue As Integer, ByRef lngEventStatus As Integer) As FT_return

    Public Declare Function FT_SetEventNotification Lib "BIKIUSB.DLL" (ByVal lngHandle As Integer, ByVal lngEventMask As Integer, ByVal lngEvent As Integer) As FT_return

    '==============================================================
    'Declarations for the EEPROM-accessing functions in FTD2XX.dll:
    '==============================================================
    'UPGRADE_WARNING: Structure FT_PROGRAM_DATA may require marshalling attributes to be passed as an argument in this Declare statement. Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="C429C3A5-5D47-4CD9-8F51-74A1616405DC"'
    Private Declare Function FT_EE_Program Lib "BIKIUSB.DLL" (ByVal lngHandle As Integer, ByRef lpData As FT_PROGRAM_DATA) As FT_return
    Private Declare Function FT_EE_Read Lib "BIKIUSB.DLL" (ByVal lngHandle As Integer, ByRef lpData As FT_PROGRAM_DATA) As FT_return
    Public Declare Function FT_EE_UASize Lib "BIKIUSB.DLL" (ByVal lngHandle As Integer, ByRef lpdwSize As Integer) As FT_return
    Public Declare Function FT_EE_UAWrite Lib "BIKIUSB.DLL" (ByVal lngHandle As Integer, ByVal pucData() As Byte, ByVal dwDataLen As Integer) As FT_return
    Public Declare Function FT_EE_UARead Lib "BIKIUSB.DLL" (ByVal lngHandle As Integer, ByVal pucData() As Byte, ByVal dwDataLen As Integer, ByRef lpdwBytesRead As Integer) As FT_return


    '====================================================================
    'UPGRADE_NOTE: object was upgraded to object_Renamed. Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="A9E4979A-37FA-4718-9994-97DD76ED70A7"'
    'UPGRADE_ISSUE: Declaring a parameter 'As Any' is not supported. Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="FAE78A8D-8978-4FD4-8208-5B7324A8F795"'
    '====================================================================
    'Type definition as equivalent for C-structure "ft_program_data" used
    'in FT_EE_READ and FT_EE_WRITE;
    'ATTENTION! The variables "Manufacturer", "ManufacturerID",
    '"Description" and "SerialNumber" are passed as POINTERS to
    'locations of Bytearrays. Each Byte in these arrays will be
    'filled with one character of the whole string.
    '(See below, calls to "agGetAddressForObject")
    '=====================================================================
    Private Structure FT_PROGRAM_DATA
        Dim VendorId As Short '0x0403
        Dim ProductId As Short '0x6001
        Dim Manufacturer As Integer '32 "FTDI"
        Dim ManufacturerId As Integer '16 "FT"
        Dim description As Integer '64 "USB HS Serial Converter"
        Dim SerialNumber As Integer '16 "FT000001" if fixed, or NULL
        Dim MaxPower As Short ' // 0 < MaxPower <= 500
        Dim PnP As Short ' // 0 = disabled, 1 = enabled
        Dim SelfPowered As Short ' // 0 = bus powered, 1 = self powered
        Dim RemoteWakeup As Short ' // 0 = not capable, 1 = capable
        ' Rev4 extensions:
        Dim Rev4 As Boolean ' // true if Rev4 chip, false otherwise
        Dim IsoIn As Boolean ' // true if in endpoint is isochronous
        Dim IsoOut As Boolean ' // true if out endpoint is isochronous
        Dim PullDownEnable As Boolean ' // true if pull down enabled
        Dim SerNumEnable As Boolean ' // true if serial number to be used
        Dim USBVersionEnable As Boolean ' // true if chip uses USBVersion
        Dim USBVersion As Short ' // BCD (0x0200 => USB2)
    End Structure

    Public Enum BikiAction As Integer
        BK_NONE = 0
        BK_MAP1 = &H1
        BK_MAP2 = &H2
        BK_MAP3 = &H4
        BK_CFG = &H8
        BK_ALL = &H10
    End Enum
    ''' <summary>
    ''' This enumator defines Integer values in byte offset from zero of the USB FT 232's EEPROM space
    ''' </summary>
    ''' <remarks></remarks>
    Public Enum Biki_USBvars As Short
        UV_Baud = 0
        UV_EcuFLASH_CRC = 2
        UV_BikEEPROM_CRC = 6
        UV_EcuFLASH_CRC_MAP_2 = &HA
        UV_EcuFLASH_CRC_MAP_3 = &HE
    End Enum

    Public Enum FT_return As Short
        FT_OK = 0
        FT_INVALID_HANDLE = 1
        FT_DEVICE_NOT_FOUND = 2
        FT_DEVICE_NOT_OPENED = 3
        FT_IO_ERROR = 4
        FT_INSUFFICIENT_RESOURCES = 5
        FT_INVALID_PARAMETER = 6
        FT_INVALID_BAUD_RATE = 7
        FT_DEVICE_NOT_OPENED_FOR_ERASE = 8
        FT_DEVICE_NOT_OPENED_FOR_WRITE = 9
        FT_FAILED_TO_WRITE_DEVICE = 10
        FT_EEPROM_READ_FAILED = 11
        FT_EEPROM_WRITE_FAILED = 12
        FT_EEPROM_ERASE_FAILED = 13
        FT_EEPROM_NOT_PRESENT = 14
        FT_EEPROM_NOT_PROGRAMMED = 15
        FT_INVALID_ARGS = 16
        FT_OTHER_ERROR = 17
    End Enum
    Public Enum BK_return As Short
        BK_OK = 0
        BK_IO_ERROR_USB = 1
        BK_IO_ERROR_BIK = 2
        BK_DEVICE_NOT_FOUND = 3
        BK_FAILED_INIT = 4
        BK_FAILED_CMD = 5
        BK_ERROR_CATCH = 6
        BK_IO_CRC_FAILED = 7
        BK_FAILED_ERASE = 8
        BK_TH_CANCELLED = 9
        BK_FIRMWARE = 10
    End Enum
    Public Enum FT_Bits As Short
        FT_BITS_8 = 8
        FT_BITS_7 = 7
    End Enum
    Public Enum FT_Stop_Bits As Short
        FT_STOP_BITS_1 = 0
        FT_STOP_BITS_1_5 = 1
        FT_STOP_BITS_2 = 2
    End Enum
    Public Enum FT_Parity As Short
        FT_PARITY_NONE = 0
        FT_PARITY_ODD = 1
        FT_PARITY_EVEN = 2
        FT_PARITY_MARK = 3
        FT_PARITY_SPACE = 4
    End Enum
    Public Enum FT_Flow As Short
        FT_FLOW_NONE = &H0S
        FT_FLOW_RTS_CTS = &H100S
        FT_FLOW_DTR_DSR = &H200S
        FT_FLOW_XON_XOFF = &H400S
    End Enum
    Public Enum FT_Purg As Short
        FT_PURGE_RX = 1
        FT_PURGE_TX = 2
    End Enum

    ' Flags for FT_OpenEx
    Const FT_OPEN_BY_SERIAL_NUMBER As Short = 1
    Const FT_OPEN_BY_DESCRIPTION As Short = 2

    ' Flags for FT_ListDevices
    Public Const FT_LIST_BY_NUMBER_ONLY As Integer = &H80000000
    Const FT_LIST_BY_INDEX As Integer = &H40000000
    Const FT_LIST_ALL As Integer = &H20000000

    Public g_baud As Integer = 500000
    Public g_packetSize As Integer = 256

    Public Function BikiRom_Init() As BK_return
        Dim f_retry As Byte = 0
        Dim f_Pass As BK_return = BK_return.BK_FAILED_INIT
        Dim f_return(0) As Byte

        Close_BikiRom()

beforeConnect:
        f_Pass = BikiRom_connect()
        If f_Pass = BK_return.BK_OK Then
            BikiRom_SetTimeout(200)
beforeInit:
            BikiRom_Flush()
            Debug.Print("connected OK")
            If BikiRom_HexCmdAA("00") Then
                Return BK_return.BK_OK
            Else
                If BikiRom_ReInit() Then
                    Debug.Print("re-init OK")
                    Return BK_return.BK_OK
                Else
                    BikiRom_Reset()
                    Dim aBytes As Byte() = BikiRom_read(4)
                    If aBytes.Length = 4 Then
                        If aBytes(1) = &HFF And _
                           aBytes(2) = &HFE And _
                           aBytes(3) = &HFF Then
                            Return BK_return.BK_FIRMWARE
                        End If
                    End If
                    Debug.Print("re-init not ok")
                    f_Pass = BK_return.BK_FAILED_INIT
                    f_retry += 1
                    If f_retry <= 10 Then GoTo beforeInit
                    GoTo CloseHandle
                End If
            End If
        Else
            Return f_Pass
            GoTo CloseHandle
        End If

        BikiRom_SetTimeout(20)
        Return f_Pass

        Exit Function

CloseHandle:
        FT_Close(lngHandle)
        Return BK_return.BK_FAILED_INIT
    End Function
    Public Function BikiRom_connect(Optional ByVal Baud As Long = 0) As BK_return

        If lngHandle <> 0 Then Close_BikiRom()

        If FT_OpenByIndex(0, lngHandle) <> FT_return.FT_OK Then
            Return BK_return.BK_DEVICE_NOT_FOUND
        End If
        FT_SetRts(lngHandle)
        Dim f_baud As Short
        GetUsbVariable(Biki_USBvars.UV_Baud, f_baud)
        If f_baud <> 0 Then g_baud = f_baud * 1000
        If Baud <> 0 Then g_baud = Baud
        If FT_SetBaudRate(lngHandle, g_baud) <> FT_return.FT_OK Then
            GoTo CloseHandle
        End If

        If FT_SetUSBParameters(lngHandle, g_packetSize + 24, g_packetSize + 24) <> FT_return.FT_OK Then
            GoTo CloseHandle
        End If
        FT_SetRts(lngHandle)
        If FT_SetDataCharacteristics(lngHandle, FT_Bits.FT_BITS_8, FT_Stop_Bits.FT_STOP_BITS_1, FT_Parity.FT_PARITY_NONE) <> FT_return.FT_OK Then
            GoTo CloseHandle
        End If
        FT_SetRts(lngHandle)
        If FT_SetFlowControl(lngHandle, FT_Flow.FT_FLOW_NONE, 0, 0) <> FT_return.FT_OK Then
            System.Diagnostics.Debug.WriteLine("SetFlowControl Failed")
            GoTo CloseHandle
        End If
        FT_SetRts(lngHandle)
        If FT_SetTimeouts(lngHandle, 200, 0) <> FT_return.FT_OK Then
            System.Diagnostics.Debug.WriteLine("SetFlowControl Failed")
            GoTo CloseHandle
        End If
        FT_SetRts(lngHandle)
        Dim lngLatency As Byte = 1
        If FT_SetLatencyTimer(lngHandle, lngLatency) <> FT_return.FT_OK Then
            System.Diagnostics.Debug.WriteLine("SetLatency Failed")
            GoTo CloseHandle
        End If
        FT_SetRts(lngHandle)

        Console.WriteLine("DUMP OF ALL BIKIROM CARIABLES STORED IN EEPROM OF USB CHIP")
        Dim f_var As UInt32
        GetUsbVariable(Biki_USBvars.UV_BikEEPROM_CRC, f_var)
        Console.WriteLine("Bikrom CRC: " & Hex(f_var))
        GetUsbVariable(Biki_USBvars.UV_EcuFLASH_CRC, f_var)
        Console.WriteLine("ECU CRC: " & Hex(f_var))
        FT_SetRts(lngHandle)

        Return BK_return.BK_OK
        Exit Function
CloseHandle:
        Console.WriteLine("Interface Closed, error")
        FT_Close(lngHandle)
        Return BK_return.BK_IO_ERROR_USB
    End Function
    Public Function usb_read(ByVal RxBytes As Integer) As Byte()
        Dim retBytes(512) As Byte
        Dim f_BytesInBuffer As Integer = 0
        FT_GetQueueStatus(lngHandle, f_BytesInBuffer)
        If RxBytes > 0 Then
            FT_Read_Bytes(lngHandle, retBytes(0), RxBytes, RxBytes)
        End If
        ReDim Preserve retBytes(RxBytes - 1)
        Return retBytes
    End Function
    Public Function BikiRom_hexCmd(ByVal Str_ As String, ByRef Return_() As Byte, ByVal retLen As Integer) As Boolean
        Dim f_cmd() As Byte = cv_BytesFromHex(Str_)
        If BikiRom_sndCmd(lngHandle, f_cmd, Return_, f_cmd.Length, retLen) Then
            Return True
        Else
            Return False
        End If
    End Function
    ''' <summary>
    ''' Send a command to the bikirom USB device and check it gives the reply given into the function
    ''' </summary>
    ''' <param name="inputStr">Command as a Hex String to send to BikiRom</param>
    ''' <param name="replyStr">BikiRom Reply Hex String validated against</param>
    ''' <returns>True if the replyStr is whats returned</returns>
    ''' <remarks></remarks>
    Public Function BikiRom_hexCmd(ByVal inputStr As String, ByVal replyStr As String) As Boolean
        Dim f_cmd() As Byte = cv_BytesFromHex(inputStr)
        Dim f_reply() As Byte = cv_BytesFromHex(replyStr)
        Dim f_return(f_reply.Length - 1) As Byte
        Dim f_result As Boolean = True
        If BikiRom_sndCmd(lngHandle, f_cmd, f_return, f_cmd.Length, f_reply.Length) Then
            For i As Integer = 0 To UBound(f_reply)
                If f_reply(i) <> f_return(i) Then f_result = False
            Next
            Return f_result
        Else
            Return False
        End If
    End Function
    Public Function BikiRom_hexCmd(ByVal Str_ As String, ByVal retLen As Integer) As Boolean
        Dim f_cmd() As Byte = cv_BytesFromHex(Str_)
        Dim f_return(0 To retLen) As Byte
        If BikiRom_sndCmd(lngHandle, f_cmd, f_return, f_cmd.Length, retLen) Then
            Return True
        Else
            Return False
        End If
    End Function
    Public Function BikiRom_hexCmd(ByVal Str_ As String) As Boolean
        Dim f_cmd() As Byte = cv_BytesFromHex(Str_)
        Dim f_return(0 To 1) As Byte
        If BikiRom_sndCmd(lngHandle, f_cmd, f_return, f_cmd.Length, 0) Then
            Return True
        Else
            Return False
        End If
    End Function
    Public Function BikiRom_HexCmdAA(ByVal str As String) As Boolean
        Dim f_cmd() As Byte = cv_BytesFromHex(str)
        Dim f_return(0 To 1) As Byte
        If BikiRom_sndCmd(lngHandle, f_cmd, f_return, f_cmd.Length, 1) Then
            If f_return(0) = &HAA Then Return True Else Return False
        Else
            Return False
        End If
    End Function
    Public Function BikiRom_sendCmdd(ByRef Send_() As Byte, ByRef Return_() As Byte, ByVal sendLen As Integer, ByVal retLen As Integer) As Boolean
        If BikiRom_sndCmd(lngHandle, Send_, Return_, sendLen, retLen) Then
            BikiRom_sendCmdd = True
        Else
            BikiRom_sendCmdd = False
        End If
    End Function
    Private Function BikiRom_sndCmd(ByRef f_lngHandle As Integer, ByRef Send_() As Byte, ByRef Return_() As Byte, ByVal sendLen As Integer, ByVal retLen As Integer) As Boolean
        Dim f_retCount As Integer
        Dim flTimedout As Boolean = False
        Dim flFatalError As Boolean = False
        Dim lngTotalBytesRead As Integer = 0
        Dim ftStatus As Short
        Dim lngBytesRead As Integer = 0
        Dim byteArray(258) As Byte
        Dim arrayCursor As Short = 0
        Dim i As Short

        If sendLen >= 1 Then
            FT_Purge(lngHandle, FT_Purg.FT_PURGE_RX + FT_Purg.FT_PURGE_TX)
        End If
        'Debug.Print ("cmd: " & cv_HexFromString(Send_) & " length: " & sendLen)
        '********************
        '** Send Command Code
        If sendLen >= 1 Then
            If FT_Write_Bytes(f_lngHandle, Send_(0), sendLen, f_retCount) <> FT_return.FT_OK Then
                Debug.Write("Error writing bytes to USB CHIP")
                Return False
                'Debug.Print ("FT_Send - send# :" & sendLen & " written: " & f_retCount)
                Exit Function
            End If
        End If
        If retLen <> 0 Then
            flTimedout = False
            flFatalError = False

            '******************
            '** Wait for number of bytes code
            lngTotalBytesRead = 0
            Do
                lngBytesRead = 0
                ftStatus = FT_Read_Bytes(f_lngHandle, byteArray(0), retLen, lngBytesRead)
                ' Debug.Print("FT_Read - send# :" & retLen & " Read: " & lngTotalBytesRead)
                If (ftStatus = FT_return.FT_OK) Or (ftStatus = FT_return.FT_IO_ERROR) Then
                    If lngBytesRead > 0 Then
                        For i = 1 To lngBytesRead
                            Return_(arrayCursor) = byteArray(i - 1)
                            arrayCursor += 1
                        Next
                        lngTotalBytesRead += lngBytesRead
                        retLen -= lngBytesRead
                    Else
                        flTimedout = True
                    End If
                Else
                    flFatalError = True
                End If
            Loop Until (lngTotalBytesRead >= retLen) Or (flTimedout = True) Or (flFatalError = True)
        Else
            FT_Purge(f_lngHandle, FT_Purg.FT_PURGE_RX)
        End If
        '*******************
        '** Return Code

        'Debug.Print("return: " & cv_HexFromString(Return_) & " bytes: " & lngTotalBytesRead)
        If flTimedout = True Or flFatalError = True Then
            Return False
        Else
            Return True
        End If
    End Function
    Public Sub BikiRom_Flush()
        FT_Purge(lngHandle, FT_Purg.FT_PURGE_TX + FT_Purg.FT_PURGE_RX)
    End Sub
    Public Function BikiRom_read(ByVal ReturnLen As Integer) As Byte()
        Dim return_(ReturnLen - 1) As Byte
        Dim f_retCount As Integer = ReturnLen
        Dim flTimedout As Boolean = False
        Dim flFatalError As Boolean = False
        Dim lngTotalBytesRead As Integer = 0
        Dim ftStatus As Short
        Dim lngBytesRead As Integer = 0
        Dim byteArray(258) As Byte
        Dim arrayCursor As Short = 0
        Dim i As Short
        Dim f_count As Integer = 0
        If ReturnLen <> 0 Then
            flTimedout = False
            flFatalError = False

            '******************
            '** Wait for number of bytes code
            lngTotalBytesRead = 0
            Do
                lngBytesRead = 0
                ftStatus = FT_Read_Bytes(lngHandle, byteArray(0), f_retCount, lngBytesRead)
                'Debug.Print("FT_Read - send# :" & f_retCount & " Read: " & lngTotalBytesRead)
                If (ftStatus = FT_return.FT_OK) Or (ftStatus = FT_return.FT_IO_ERROR) Then
                    If lngBytesRead > 0 Then
                        For i = 1 To lngBytesRead
                            return_(arrayCursor) = byteArray(i - 1)
                            arrayCursor += 1
                        Next
                        lngTotalBytesRead += lngBytesRead
                        f_retCount -= lngBytesRead
                    Else
                        flTimedout = True
                    End If
                Else
                    flFatalError = True
                End If
            Loop Until (lngTotalBytesRead >= ReturnLen) Or (flTimedout = True) Or (flFatalError = True)
        Else
            FT_Purge(lngHandle, FT_Purg.FT_PURGE_RX)
        End If
        '*******************
        '** Return Code
        'Debug.Print("timeout: " & flTimedout & " Ioerror: " & flFatalError)
        Return return_
    End Function

    ''' <summary>
    ''' Functions below read data from the USB FT232's EEPROM space and write to it in a quick and easy fassion
    ''' </summary>
    ''' <remarks>These functions Assume that you already have a USB connection to the device</remarks>
    Public Function GetUsbVariable(ByVal var As Biki_USBvars, ByRef oIntValue As Short) As Boolean
        Dim f_size As Integer
        If FT_EE_UASize(lngHandle, f_size) = FT_return.FT_OK Then
            If var + 1 >= f_size Then Return False : Exit Function
            Dim f_bytes(f_size - 1) As Byte
            Dim f_read As Integer
            If FT_EE_UARead(lngHandle, f_bytes, 26, f_read) = FT_return.FT_OK Then
                oIntValue = MAKEWORD(f_bytes(var + 1), f_bytes(var))
                Return True
            Else : Return False
            End If
        Else : Return False
        End If
    End Function
    Public Function GetUsbVariable(ByVal var As Biki_USBvars, ByRef oIntValue As UInt32) As Boolean
        Dim f_size As Integer
        If FT_EE_UASize(lngHandle, f_size) = FT_return.FT_OK Then
            If var + 1 >= f_size Then Return False : Exit Function
            Dim f_bytes(f_size - 1) As Byte
            Dim f_read As Integer
            If FT_EE_UARead(lngHandle, f_bytes, 26, f_read) = FT_return.FT_OK Then
                Select Case var
                    Case Biki_USBvars.UV_Baud
                        oIntValue = MAKEWORD(f_bytes(var + 1), f_bytes(var))
                    Case Biki_USBvars.UV_EcuFLASH_CRC To Biki_USBvars.UV_EcuFLASH_CRC_MAP_3
                        oIntValue = makeLong(f_bytes(var), f_bytes(var + 1), f_bytes(var + 2), f_bytes(var + 3))
                End Select
                Return True
            Else : Return False
            End If
        Else : Return False
        End If
    End Function
    Public Function SetUsbVariable(ByVal var As Biki_USBvars, ByVal sIntValue As UInt32) As Boolean
        Dim f_size As Integer
        If FT_EE_UASize(lngHandle, f_size) = FT_return.FT_OK Then
            If var + 1 >= f_size Then Return False : Exit Function
            Dim f_bytes(25) As Byte
            Dim f_read As Integer
            If FT_EE_UARead(lngHandle, f_bytes, 26, f_read) = FT_return.FT_OK Then
                Select Case var
                    Case Biki_USBvars.UV_Baud
                        f_bytes(var + 1) = LOBYTE(sIntValue)
                        f_bytes(var) = HIBYTE(sIntValue)
                    Case Biki_USBvars.UV_EcuFLASH_CRC To Biki_USBvars.UV_EcuFLASH_CRC_MAP_3
                        f_bytes(var) = HIBYTE(hiInt(sIntValue))
                        f_bytes(var + 1) = LOBYTE(hiInt(sIntValue))
                        f_bytes(var + 2) = HIBYTE(loInt(sIntValue))
                        f_bytes(var + 3) = LOBYTE(loInt(sIntValue))
                End Select
                If FT_EE_UAWrite(lngHandle, f_bytes, 26) = FT_return.FT_OK Then Return True Else Return False
            Else : Return False
            End If
        Else : Return False
        End If
    End Function

    Private Function inv(ByRef byte_ As Byte) As Byte
        inv = 0
        Dim m_loop As Byte

        For m_loop = 0 To 7
            If BitIsSet_byte(byte_, m_loop) Then
                inv = BitSet_byte(inv, 7 - m_loop)
            End If
        Next
    End Function

    Public Sub Close_BikiRom()
        If FT_Close(lngHandle) = FT_return.FT_OK Then
            lngHandle = 0
        End If
    End Sub
    Public Function Crc_byte(ByRef first_ As Byte, ByRef second_ As Byte) As Byte
        If first_ = second_ Then
            Crc_byte = 0
        Else
            Crc_byte = first_ Xor second_
        End If
    End Function
    Private Function byte_String(ByRef byte_ As Byte) As String
        If byte_ <= 15 Then
            byte_String = "0" & Mid(Hex(byte_), 2, 1)
        Else
            byte_String = Hex(byte_)
        End If
    End Function
    Public Function BikiRom_UploadSector(ByVal sector As Byte, ByRef b_array() As Byte) As Boolean
        Dim i As Object
        Dim cmd() As Byte = Nothing
        Dim ret(512) As Byte
        Dim m_cursor As Double
        Dim s_crc As Double
        Dim s_data(512) As Byte
        Dim s_error As Byte
        Dim s_init() As Byte = {0}

        If lngHandle <> 0 And sector >= 0 And sector <= 3 Then

            ' Setup the Upload and start command
            Select Case sector
                Case 0
                    cmd = cv_BytesFromHex("CC3100AF0000")
                    Err_message(cv_StrFromBytes(cmd))
                    Err_message("sector 1")
                Case 1
                    cmd = cv_BytesFromHex("CC3100AF7FFF")
                    Err_message(cv_StrFromBytes(cmd))
                    Err_message("sector 2")
                Case 2
                    cmd = cv_BytesFromHex("CC3101AF0000")
                    Err_message(cv_StrFromBytes(cmd))
                    Err_message("sector 3")
                Case 3
                    cmd = cv_BytesFromHex("CC3101AF7FFF")
                    Err_message("sector 4")
                    Err_message(cv_StrFromBytes(cmd))
            End Select
            ' Erase Sector First
            'If Not BikiRom_EraseSector(sector) Then
            ' BikiRom_UploadSector = False
            ' Err_message("erase not ok")
            ' Exit Function
            'End If


            BikiRom_ReInit()
            ' Send command
            If BikiRom_sendCmdd(cmd, ret, 6, 2) = True Then
                If ret(1) = 170 Then
                    BikiRom_UploadSector = True
                Else
                    BikiRom_UploadSector = False
                    Err_message("return not correct")
                    Exit Function
                End If
            Else
                BikiRom_UploadSector = False
                Err_message("timout")
                Exit Function
            End If

            ' Upload Data
            s_data(0) = 223
            For m_cursor = 0 To 65535 Step g_packetSize

                ' Copy and Calculate Crc byte
                s_crc = 0
                array_copy(b_array, m_cursor, s_data, 1, g_packetSize)
                For i = 1 To g_packetSize
                    s_crc = s_crc + CByte(s_data(i))
                Next
                s_data(g_packetSize + 1) = LOBYTE(s_crc)
reSend:
                ' Send Data packet
                If BikiRom_sendCmdd(s_data, ret, g_packetSize + 2, 1) = False Then
                    Err_message("error sending data paccket")
                    BikiRom_UploadSector = False
                    Exit Function
                Else
                    If ret(0) <> 223 Then
                        'System.Diagnostics.Debug.WriteLine("adr: " & Hex(m_cursor) & " " & cv_HexFromBytes(s_data) & " " & cv_HexFromBytes(ret) & " " & Hex(s_crc) & " " & Hex(s_data(257)))
                        s_error = s_error + 1
                        If s_error >= 100 Then
                            BikiRom_UploadSector = False
                            Err_message("lots of errors")
                            Exit Function
                        End If
                        GoTo reSend
                    End If
                End If

                ' Calculate Progress
                If (m_cursor Mod 1024) = 0 Then
                    StatusPercent(((m_cursor / 65536) * 100))
                End If
            Next

            ' Send End Marker Packet
            'UPGRADE_WARNING: Couldn't resolve default property of object cv_BytesFromHex(). Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
            cmd = cv_BytesFromHex("FF")
            If BikiRom_sendCmdd(cmd, ret, 1, 1) Then
                StatusPercent((100))
                Return True
            Else
                Return False
            End If
        Else
            Return False
        End If
    End Function
    Public Sub BikiRom_SetTimeoutHigh(ByVal bool As Boolean)
        If bool Then
            FT_SetTimeouts(lngHandle, 10000, 0)
        Else
            FT_SetTimeouts(lngHandle, 100, 0)
        End If
    End Sub
    Public Sub BikiRom_SetTimeout(ByVal TimeOut As Integer)
        FT_SetTimeouts(lngHandle, TimeOut, TimeOut)
    End Sub

    ' This function Takes 0-4 and erases that sector or entire flash for mode 4
    Public Function BikiRom_EraseSector(ByVal sector As Integer) As Boolean
        Dim cmd() As Byte
        Dim s_init() As Byte = {0}
        Dim ret(10) As Byte

        If lngHandle <> 0 And sector >= 0 And sector <= 4 Then
            BikiRom_SetTimeoutHigh(True)
            Select Case sector
                Case BikiAction.BK_MAP1
                    cmd = cv_BytesFromHex("CC3400AF0000")
                    GoTo singleCmd
                Case BikiAction.BK_MAP2
                    cmd = cv_BytesFromHex("CC3400AF8000")
                    GoTo singleCmd
                Case BikiAction.BK_MAP3
                    cmd = cv_BytesFromHex("CC3401AF0000")
                    GoTo singleCmd
                Case BikiAction.BK_CFG
                    cmd = cv_BytesFromHex("CC3401AF8000")
                    If BikiRom_sendCmdd(cmd, ret, 6, 2) = True Then
                        If ret(1) = 170 Then
                            BikiRom_EraseSector = True
                        Else
                            BikiRom_EraseSector = False
                            Exit Function
                        End If
                    Else
                        BikiRom_EraseSector = False
                        Exit Function
                    End If
                    cmd = cv_BytesFromHex("CC3401AFC000")
                    If BikiRom_sendCmdd(cmd, ret, 6, 2) = True Then
                        If ret(1) = 170 Then
                            BikiRom_EraseSector = True
                        Else
                            BikiRom_EraseSector = False
                            Exit Function
                        End If
                    Else
                        BikiRom_EraseSector = False
                        Exit Function
                    End If
                    cmd = cv_BytesFromHex("CC3401AFD000")
                    BikiRom_sendCmdd(s_init, ret, 1, 0)
                    System.Threading.Thread.Sleep(20)

                    If BikiRom_sendCmdd(cmd, ret, 6, 2) = True Then
                        If ret(1) = 170 Then
                            BikiRom_EraseSector = True
                        Else
                            BikiRom_EraseSector = False
                            Exit Function
                        End If
                    Else
                        BikiRom_EraseSector = False
                        Exit Function
                    End If
                    cmd = cv_BytesFromHex("CC3401AFE000")
                    BikiRom_sendCmdd(s_init, ret, 1, 0)
                    System.Threading.Thread.Sleep(20)

                    If BikiRom_sendCmdd(cmd, ret, 6, 2) = True Then
                        If ret(1) = 170 Then
                            BikiRom_EraseSector = True
                        Else
                            BikiRom_EraseSector = False
                            Exit Function
                        End If
                    Else
                        BikiRom_EraseSector = False
                        Exit Function
                    End If
                Case BikiAction.BK_ALL
                    cmd = cv_BytesFromHex("CC3300")
                    If BikiRom_sendCmdd(cmd, ret, 3, 1) = True Then
                        If ret(0) = 170 Then
                            BikiRom_EraseSector = True
                        Else
                            BikiRom_EraseSector = False
                        End If
                    Else
                        BikiRom_EraseSector = False
                    End If
            End Select
        End If
        BikiRom_SetTimeoutHigh(False)
        Exit Function
singleCmd:
        If BikiRom_sendCmdd(cmd, ret, 6, 2) = True Then
            If ret(2) = 170 Then
                BikiRom_EraseSector = True
            Else
                BikiRom_EraseSector = False
            End If
        Else
            BikiRom_EraseSector = False
        End If
        BikiRom_SetTimeoutHigh(False)
    End Function
    Public Function BikiRom_DownloadSector(ByVal sector As Byte, ByRef b_array() As Byte) As Boolean
        Dim e As Object
        Dim s_crc, m_loop As Double
        Dim cmd() As Byte = Nothing
        Dim s_error As Byte
        Dim ret(512) As Byte

        If lngHandle <> 0 And sector >= 0 And sector <= 3 Then
            ' Setup the download and start command
            Select Case sector
                Case 0
                    'UPGRADE_WARNING: Couldn't resolve default property of object cv_BytesFromHex(). Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
                    cmd = cv_BytesFromHex("CC3200AF0000")
                Case 1
                    'UPGRADE_WARNING: Couldn't resolve default property of object cv_BytesFromHex(). Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
                    cmd = cv_BytesFromHex("CC3200AF8000")
                Case 2
                    'UPGRADE_WARNING: Couldn't resolve default property of object cv_BytesFromHex(). Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
                    cmd = cv_BytesFromHex("CC3201AF0000")
                Case 3
                    'UPGRADE_WARNING: Couldn't resolve default property of object cv_BytesFromHex(). Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
                    cmd = cv_BytesFromHex("CC3201AF7FFF")
            End Select

            BikiRom_ReInit()

            ' Send command
            If BikiRom_sendCmdd(cmd, ret, 6, 2) = True Then
                If ret(1) = 170 Then
                    BikiRom_DownloadSector = True
                Else
                    BikiRom_DownloadSector = False
                    Exit Function
                End If
            Else
                BikiRom_DownloadSector = False
                Exit Function
            End If

            ' Download Data
            'UPGRADE_WARNING: Couldn't resolve default property of object cv_BytesFromHex(). Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
            cmd = cv_BytesFromHex("DF")
            For m_loop = 0 To 65536 - g_packetSize Step g_packetSize
repeat:
                ' Send download Command
                If Not BikiRom_sendCmdd(cmd, ret, 1, g_packetSize + 2) Then
                    BikiRom_DownloadSector = False
                    Exit Function
                End If

                ' Calculate CRC
                s_crc = 0
                For e = 1 To g_packetSize
                    'UPGRADE_WARNING: Couldn't resolve default property of object e. Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
                    s_crc = s_crc + ret(e)
                Next

                ' Check CRC and copy data
                If LOBYTE(s_crc) <> ret(g_packetSize + 1) Then
                    s_error = s_error + 1
                    If s_error > 100 Then
                        BikiRom_DownloadSector = False
                        Exit Function
                    End If
                    GoTo repeat
                Else
                    array_copy(ret, 1, b_array, m_loop, g_packetSize)
                End If
                'UPGRADE_WARNING: Mod has a new behavior. Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="9B7D5ADD-D8FE-4819-A36C-6DEDAF088CC7"'
                If m_loop Mod 1024 = 0 Then
                    StatusPercent(((m_loop / 65536) * 100)) ' m_fileLength) * 100
                End If
            Next
            BikiRom_DownloadSector = True
        End If
    End Function
    ''' <summary>
    ''' Uploads an array given the mode change command in modeStr
    ''' </summary>
    ''' <param name="modeStr">Mode Change String</param>
    ''' <param name="data">Array to upload</param>
    ''' <param name="Packets">Number of 256byte packets to upload</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function BikiRom_UploadWcmd(ByVal modeStr As String, ByRef data() As Byte, ByVal Packets As Byte) As BK_return
        ' Upload Data
        Dim f_return As BK_return
        Dim ret(16) As Byte
        Dim s_data(257) As Byte
        Dim s_crc As Long
        Dim s_error As Int16
        s_data(0) = 223
        If Not IsNothing(data) And Packets >= 1 And UBound(data) >= (Packets * 256) - 1 Then
            f_return = BikiRom_Init()
            If f_return = BK_return.BK_OK Then
                BikiRom_SetTimeout(4000)
                If BikiRom_HexCmdAA(modeStr) Then
                    For m_cursor As Integer = 0 To (Packets - 1)
                        s_crc = 0
                        array_copy(data, m_cursor * 256, s_data, 1, g_packetSize)
                        For i As Integer = 1 To 256
                            s_crc += CByte(s_data(i))
                        Next
                        s_data(257) = LOBYTE(s_crc)
reSend:
                        ' Send Data packet
                        If BikiRom_sendCmdd(s_data, ret, g_packetSize + 2, 1) = False Then
                            Debug.Print("Packet NO RETURN")
                            Return BK_return.BK_IO_ERROR_BIK
                            GoTo close
                        Else
                            If ret(0) <> &HDF Then
                                Debug.Print("Packet return NOT OK")
                                s_error += 1
                                If s_error >= 10 Then Return BK_return.BK_IO_ERROR_BIK : GoTo close
                                GoTo reSend
                            End If
                        End If
                    Next
                    If BikiRom_hexCmd("FF") Then Return BK_return.BK_OK Else Return BK_return.BK_FAILED_CMD
close:
                Else
                    Debug.Print("mode change not ok")
                End If
            Else : Return f_return
            End If
        Else : Return BK_return.BK_ERROR_CATCH
        End If
    End Function
    Public Function BikiRom_DownloadWcmd(ByVal modeChange As String, ByVal Packets As Short) As Byte()
        Dim f_return() As Byte = Nothing
        If BikiRom_Init() = BK_return.BK_OK Then
            BikiRom_SetTimeout(4000)
            If BikiRom_HexCmdAA(modeChange) Then
                ReDim f_return((Packets * 256) - 1)
                Dim ret(260) As Byte
                Dim s_crc As Long
                Dim s_error As Int16 = 0

                For m_loop As Integer = 0 To Packets - 1
repeat:
                    ' Send download Command --------------------------------------------------------------------------------
                    If Not BikiRom_hexCmd("DF", ret, 258) Then f_return = Nothing : GoTo close

                    ' Calculate CRC ----------------------------------------------------------------------------------------
                    s_crc = 0 : For crc As Int32 = 1 To 256 : s_crc += ret(crc) : Next

                    ' Check CRC and copy data ------------------------------------------------------------------------------
                    If LOBYTE(s_crc) <> ret(257) Then : s_error += 1 : If s_error > 10 Then f_return = Nothing : GoTo close
                    Else
                        array_copy(ret, 1, f_return, m_loop * 256, 256)
                    End If
                Next
            Else : f_return = Nothing
            End If
        Else : f_return = Nothing
        End If
close:
        Return f_return
    End Function
    Public Sub BikiRom_Reset()
        FT_SetRts(lngHandle)
        Threading.Thread.Sleep(20)
        FT_SetDtr(lngHandle)
        Threading.Thread.Sleep(20)
        FT_ClrDtr(lngHandle)
        Threading.Thread.Sleep(20)
    End Sub
    Public Function BikiRom_ReInit() As Boolean
        Dim s_init() As Byte = {0}
        Dim ret(3) As Byte
        Dim s_try As Byte = 1
retry:
        BikiRom_Reset()
        System.Threading.Thread.Sleep(600 * s_try)
        BikiRom_Flush()
        If BikiRom_HexCmdAA("00") Then
            Return True
        Else
            If s_try <= 3 Then
                s_try += 1
                GoTo retry
            Else
                Return False
            End If
        End If
    End Function
    Public Sub BikiRom_BootMode()
        Threading.Thread.Sleep(20)
        FT_ClrRts(lngHandle)
        Threading.Thread.Sleep(20)
        FT_SetDtr(lngHandle)
        Threading.Thread.Sleep(20)
        FT_ClrDtr(lngHandle)
    End Sub
    Public Function consult_mode() As Boolean
        Dim f_consultMode() As Byte = cv_BytesFromHex("CC8100")
        Dim f_consultInit() As Byte = cv_BytesFromHex("FFFFEF")
        Dim f_return(30) As Byte
        If BikiRom_Init() Then
            Threading.Thread.Sleep(50)
            'BikiRom_SetTimeoutHigh(True)
            If BikiRom_sendCmdd(f_consultMode, f_return, 3, 1) Then
                If f_return(0) = 170 Then
                    If BikiRom_sendCmdd(f_consultInit, f_return, 3, 1) Then
                        If f_return(0) <> 16 And f_return(0) <> 0 Then
                            Console.WriteLine("Error from init commmand")
                            Return Nothing
                            Exit Function
                        End If
                    End If
                Else
                    Console.WriteLine("error sending init command")
                    Return Nothing
                    Exit Function
                End If
            Else
                Return Nothing
                Console.WriteLine("Error on return value from consult mode")
                Exit Function
            End If
            Return True
        Else
            Return False
        End If
    End Function
    Public Function Consult_Download(ByVal address As Integer, ByVal length As Integer) As Byte()
        Dim f_return(256) As Byte
        Dim f_array() As Byte
        ReDim f_array(length - 1)
        Dim f_consultMode() As Byte = cv_BytesFromHex("CC8100")
        Dim f_consultInit() As Byte = cv_BytesFromHex("FFFFEF")



        ' Inital command
        Dim f_cmd() As Byte = cv_BytesFromHex("C90000C90000C90000C90000F0")
        Dim f_stop() As Byte = cv_BytesFromHex("30")
        Dim f_enter() As Byte = cv_BytesFromHex("00")
        Dim f_reinit() As Byte = cv_BytesFromHex("CC8100")
        Dim f_error As Integer = 0
        Dim f_stream(0 To 120) As Byte
        Dim f_filter() As Byte
        Dim fnum As Integer = FreeFile()
        'BikiRom_SetTimeoutHigh(True)
        ' Formulate command and prepare to send

        For i As Integer = address To address + length - 4 Step 4
retry:
            Console.WriteLine("at adr: " & Hex(i))
            f_error = 0
            Threading.Thread.Sleep(10)
            For s As Integer = 0 To 3
                f_cmd((s * 3) + 1) = HIBYTE(s + i)
                f_cmd((s * 3) + 2) = LOBYTE(s + i)
            Next
            For Each by As Byte In f_stream
                by = 0
            Next
            If BikiRom_sendCmdd(f_cmd, f_stream, 13, 30) Then
                Debug.Print("Inside the F0 wait!")
                BikiRom_hexCmd("30")
                f_filter = consult_Filter(f_stream, 4)
                If Not IsNothing(f_filter) Then
                    array_copy(f_filter, 0, f_array, i - address, 4)
                    'FilePut(fnum, f_filter, i + 1)
                    Debug.Print("packet filtered ok")
                Else
                    f_error += 1
                    'debug_dump_array(f_return, 0, 32)
                    Console.WriteLine("Error in sync at: " & Hex(i))
                    If f_error >= 5 Then
                        Console.WriteLine("Alot of errors at: " & Hex(i))
                        Return Nothing
                        Exit Function
                    End If
                    Threading.Thread.Sleep(5)
                    FT_Purge(lngHandle, FT_Purg.FT_PURGE_RX)
                    GoTo retry
                End If
            Else
                Console.WriteLine("Error sending Bytes")
                BikiRom_ReInit()
                Threading.Thread.Sleep(10)
                BikiRom_sendCmdd(f_reinit, f_return, 3, 1)
                Threading.Thread.Sleep(5)
                If BikiRom_sendCmdd(f_consultInit, f_return, 3, 1) Then
                    If f_return(0) = 16 Or f_return(0) = 0 Then
                        Console.WriteLine("Re-init consult OK")
                    Else
                        Console.WriteLine("Re-init consult Not OK")
                    End If
                Else
                    Console.WriteLine("Re-init consult NOT OK")
                End If
                If f_error >= 5 Then Return Nothing : Exit Function
                f_error += 1
                GoTo retry
            End If
            'StatusPercent(((i - Car_.getDataStart) / (Car_.getDataEnd - Car_.getDataStart)) * 100)
        Next
        Return f_array
    End Function
    
    Public Function consult_Filter(ByRef Stream_() As Byte, ByVal Size_ As Byte) As Byte()
        Dim f_return(0 To Size_ - 1) As Byte
        Dim found As Boolean = False
        Dim i As Integer
        If Stream_.Length >= Size_ + 2 Then
            For i = 0 To UBound(Stream_) - Size_ - 4
                If Stream_(i) = 255 And Stream_(i + 1) = Size_ And Stream_(i + 2 + Size_) = 255 And Stream_(i + 3 + Size_) = Size_ Then
                    found = True
                    Exit For
                End If
            Next
            If found Then
                array_copy(Stream_, i + 2, f_return, 0, Size_)
                Return f_return
            Else
                Return Nothing
            End If
        Else
            Return Nothing
        End If
    End Function
End Module